import type { MaterialParams } from '@/RoomDesign/domain/global/typeHelper'
import { DoubleSide, Material, MeshBasicMaterial } from 'three'
import type { TextureResult } from '../dto/TextureResult'
import type { MaterialResult } from '../dto/MaterialResult'

export class ThreeMaterialManager {
  private static _instance: ThreeMaterialManager

  private _materialMap_basic: Map<string, MeshBasicMaterial> = new Map()

  private constructor() {}

  public static getInstance(): ThreeMaterialManager {
    if (!ThreeMaterialManager._instance) {
      ThreeMaterialManager._instance = new ThreeMaterialManager()
    }
    return ThreeMaterialManager._instance
  }

  public getMaterial(textureResult: TextureResult, materialParams: MaterialParams): MaterialResult {

    const materialId = this.getMaterialId(textureResult.textureId, materialParams)

    let material: Material;
    switch (materialParams.materialType) {
      case 'Basic':
        material = this.getMaterial_basic(textureResult, materialId);
        break;
      default:
        throw new Error('暂不支持该materialType类型')
    }

    return {
      materialId: materialId,
      material,
    }
  }

  private getMaterialId(textureId: string, materialParams: MaterialParams) {
    return materialParams.materialType + ':' + textureId
  }

  /** 获取basic材质
   * @param textureResult
   * @param materialId
   * @returns
   */
  private getMaterial_basic(textureResult: TextureResult, materialId: string): MeshBasicMaterial {
    if (this._materialMap_basic.has(materialId)) {
      return this._materialMap_basic.get(materialId) as MeshBasicMaterial
    }
    else {
      const material = new MeshBasicMaterial({
        map: textureResult.texture,
        side: DoubleSide,
      });
      this._materialMap_basic.set(materialId, material)

      return material
    }
  }
}
